home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / emula / arosdv19.lha / AROS / exec / copymem.c < prev    next >
C/C++ Source or Header  |  1996-10-24  |  3KB  |  169 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: copymem.c,v 1.8 1996/10/24 15:50:46 aros Exp $
  4.     $Log: copymem.c,v $
  5.     Revision 1.8  1996/10/24 15:50:46  aros
  6.     Use the official AROS macros over the __AROS versions.
  7.  
  8.     Revision 1.7  1996/10/23 14:21:28  aros
  9.     Renamed a few macros from XYZ to AROS_XYZ so we know which if from AROS and
  10.     which not.
  11.  
  12.     Revision 1.6  1996/10/19 17:07:25  aros
  13.     Include <aros/machine.h> instead of machine.h
  14.  
  15.     Revision 1.5  1996/09/13 17:51:22  digulla
  16.     Use IPTR
  17.  
  18.     Revision 1.4  1996/08/13 13:55:59  digulla
  19.     Replaced AROS_LA by AROS_LHA
  20.     Replaced some AROS_LH*I by AROS_LH*
  21.     Sorted and added includes
  22.  
  23.     Revision 1.3  1996/08/01 17:41:07  digulla
  24.     Added standard header for all files
  25.  
  26.     Desc:
  27.     Lang:
  28. */
  29. #include <aros/libcall.h>
  30. #include <aros/machine.h>
  31.  
  32. /*****************************************************************************
  33.  
  34.     NAME */
  35.     #include <clib/exec_protos.h>
  36.  
  37.     AROS_LH3I(void, CopyMem,
  38.  
  39. /*  SYNOPSIS */
  40.     AROS_LHA(APTR,  source, A0),
  41.     AROS_LHA(APTR,  dest,   A1),
  42.     AROS_LHA(ULONG, size,   D0),
  43.  
  44. /*  LOCATION */
  45.     struct ExecBase *, SysBase, 104, Exec)
  46.  
  47. /*  FUNCTION
  48.     Copy some memory from one destination in memory to another using
  49.     a fast copying method.
  50.  
  51.     INPUTS
  52.     source - Pointer to source area
  53.     dest   - Pointer to destination
  54.     size   - number of bytes to copy
  55.  
  56.     RESULT
  57.  
  58.     NOTES
  59.     The source and destination area are not allowed to overlap.
  60.  
  61.     EXAMPLE
  62.  
  63.     BUGS
  64.  
  65.     SEE ALSO
  66.     CopyMemQuick()
  67.  
  68.     INTERNALS
  69.  
  70.     HISTORY
  71.     24-10-95    Created by M. Fleischer
  72.  
  73. ******************************************************************************/
  74. {
  75.     AROS_LIBFUNC_INIT
  76.  
  77.     UBYTE *src=(UBYTE *)source,*dst=(UBYTE *)dest;
  78.     ULONG mis,low,high;
  79.  
  80.     /*
  81.     I try to fall back to copying LONGs if possible. To do this I copy
  82.     the misaligned leading bytes of the source first. I use sizeof(LONG)
  83.     instead of LONGALIGN because it is sometimes faster.
  84.     */
  85.     mis =(IPTR)src&(sizeof(LONG)-1);
  86.     if(mis>size)
  87.     mis=size;
  88.     size-=mis;
  89.  
  90.     if(mis)
  91.       do
  92.     *dst++=*src++;
  93.       while(--mis);
  94.  
  95.     /*
  96.     The source has the right alignment now. All I need to do is to
  97.     check if this is true for the destination, too.
  98.     */
  99.     if(!((IPTR)dst&(AROS_LONGALIGN-1)))
  100.     {
  101.     /* Yes. I may copy LONGs. */
  102.     LONG *s=(LONG *)src,*d=(LONG *)dst;
  103.     ULONG longs;
  104.  
  105.     /* How many of them? */
  106.     longs=size/sizeof(LONG);
  107.  
  108.     /*
  109.         To minimize the loop overhead I copy more than one (eight) LONG per
  110.         iteration. Therefore I need to split size into size/8 and the rest.
  111.     */
  112.     low =longs&7;
  113.     high=longs/8;
  114.  
  115.     /* Then copy for both parts */
  116.     if(low)
  117.         do
  118.         *d++=*s++;
  119.         while(--low);
  120.  
  121.     if(high)
  122.         do
  123.         {
  124.         *d++=*s++;
  125.         *d++=*s++;
  126.         *d++=*s++;
  127.         *d++=*s++;
  128.         *d++=*s++;
  129.         *d++=*s++;
  130.         *d++=*s++;
  131.         *d++=*s++;
  132.         }while(--high);
  133.  
  134.     /* Get the rest. */
  135.     size&=sizeof(LONG)-1;
  136.     src=(UBYTE *)s;
  137.     dst=(UBYTE *)d;
  138.     }
  139.  
  140.     /* The remaining job can only be done by copying single bytes. */
  141.     low =size&7;
  142.     high=size/8;
  143.  
  144.     /* Copy for both parts */
  145.     if(low)
  146.       do
  147.     *dst++=*src++;
  148.       while(--low);
  149.  
  150.     /*
  151.     Partly unrolled copying loop. The predecrement helps the compiler to
  152.     find the best possible loop. The if is necessary to do this.
  153.     */
  154.     if(high)
  155.     do
  156.     {
  157.         *dst++=*src++;
  158.         *dst++=*src++;
  159.         *dst++=*src++;
  160.         *dst++=*src++;
  161.         *dst++=*src++;
  162.         *dst++=*src++;
  163.         *dst++=*src++;
  164.         *dst++=*src++;
  165.     }while(--high);
  166.     AROS_LIBFUNC_EXIT
  167. } /* CopyMem */
  168.  
  169.